<template>
  <view class="video-upload-container">
    <view v-if="!uploadedVideoUrl" class="upload-area">
      <view v-if="!uploading && !uploadError" class="upload-btn" @click="selectVideo">
        <uni-icons type="videocam" size="24" color="#007AFF"></uni-icons>
        <text class="upload-text">点击上传视频</text>
        <text class="upload-hint">支持拍摄或相册选择，最大60秒</text>
      </view>
      <view v-if="uploading" class="upload-progress">
        <view class="progress-bar">
          <view class="progress-fill" :style="{ width: uploadProgress + '%' }"></view>
        </view>
        <text class="progress-text">上传中... {{ uploadProgress }}%</text>
        <button class="btn-small cancel" @click="cancelUpload">取消</button>
      </view>
      <view v-if="uploadError" class="upload-error">
        <text class="error-text">{{ uploadError }}</text>
        <button class="btn-small retry" @click="retryUpload">重试</button>
      </view>
    </view>
    <view v-if="uploadedVideoUrl" class="uploaded-area">
      <view class="video-preview-wrapper">
        <view class="video-thumbnail-wrapper" @click="showFullscreenVideo">
          <view class="play-overlay" v-if="uploadedVideoUrl">
            <text class="play-text">▶</text>
          </view>
          <view class="delete-btn" @click.stop="removeVideo" v-if="uploadedVideoUrl">
            <text class="delete-text">×</text>
          </view>
        </view>
      </view>
    </view>
    <!-- 播放改为跳转预览页面，避免浮层在手机端难以关闭的问题 -->
  </view>
</template>

<script>
import upload from '@/utils/upload'
import { getToken } from '@/utils/auth'

export default {
  name: 'VideoUpload',
  props: {
    urlOnly: { type: Boolean, default: false }
  },
  data() {
    return {
      uploadedVideoUrl: '',
      uploading: false,
      uploadProgress: 0,
      selectedVideoFile: null,
      uploadError: '',
      showFullscreen: false,
      thumbError: false,
      // 上传相关状态
      lastProgress: -1, // 记录上次进度，避免重复打印
      uploadTask: null // 上传任务句柄
    }
  },
  components: { },
  watch: {
    uploadedVideoUrl(newVal) {
      // 简化：不再生成缩略图
    }
  },
  methods: {
    selectVideo() {
      this.uploadError = ''
      this.uploading = false
      this.selectedVideoFile = null
      uni.showActionSheet({
        itemList: ['拍摄视频', '从相册选择'],
        success: (res) => {
          if (res.tapIndex === 0) this.chooseVideo('camera')
          else if (res.tapIndex === 1) this.chooseVideo('album')
        },
        fail: () => {
          this.uploadError = ''
          this.uploading = false
          this.selectedVideoFile = null
        }
      })
    },
    chooseVideo(sourceType) {
      this.uploadError = ''
      this.uploading = false
      this.selectedVideoFile = null
      uni.chooseVideo({
        sourceType: [sourceType],
        maxDuration: 60,
        camera: 'back',
        compressed: false,
        success: (res) => {
          // 详细打印视频信息
          const videoSizeBytes = res.size || 0
          const videoSizeMB = videoSizeBytes / (1024 * 1024)
          const videoSizeKB = videoSizeBytes / 1024
          const duration = res.duration || 0
          const width = res.width || 0
          const height = res.height || 0
          
          console.log('========== 视频信息 ==========')
          console.log('文件大小（字节）:', videoSizeBytes.toLocaleString(), 'bytes')
          console.log('文件大小（KB）:', videoSizeKB.toFixed(2), 'KB')
          console.log('文件大小（MB）:', videoSizeMB.toFixed(2), 'MB')
          console.log('视频时长:', duration, '秒')
          console.log('视频尺寸:', width + 'x' + height)
          console.log('文件路径:', res.tempFilePath)
          console.log('============================')
          
          // 服务器限制是50MB
          const SERVER_MAX_SIZE_MB = 50
          
          // 超过50MB必须压缩
          if (videoSizeMB > SERVER_MAX_SIZE_MB) {
            uni.showModal({
              title: '文件过大',
              content: `视频文件大小为 ${videoSizeMB.toFixed(2)}MB，超过服务器限制（${SERVER_MAX_SIZE_MB}MB）。必须压缩后上传。`,
              showCancel: false,
              success: (modalRes) => {
                if (modalRes.confirm) {
                  this.compressVideo(res)
                }
              }
            })
            return
          }
          
          // 49MB以上（非常接近50MB限制）给出警告，但仍允许直接上传
          if (videoSizeMB >= 49) {
            uni.showModal({
              title: '警告',
              content: `视频文件大小为 ${videoSizeMB.toFixed(2)}MB，非常接近服务器限制（${SERVER_MAX_SIZE_MB}MB）。如果上传失败，请压缩后重试。`,
              success: (modalRes) => {
                if (modalRes.confirm) {
                  // 用户选择继续，直接上传
                  uni.showToast({
                    title: '正在上传，文件较大可能需要较长时间',
                    icon: 'none',
                    duration: 3000
                  })
                  this.selectedVideoFile = res
                  this.startUpload(res)
                } else {
                  // 用户选择取消，可以选择压缩
                  uni.showModal({
                    title: '是否压缩',
                    content: '是否压缩视频后再上传？',
                    success: (compressRes) => {
                      if (compressRes.confirm) {
                        this.compressVideo(res)
                      }
                    }
                  })
                }
              }
            })
          } else {
            // 50MB以下直接上传，不再提示压缩
            if (videoSizeMB >= 20) {
              uni.showToast({
                title: `正在上传 ${videoSizeMB.toFixed(2)}MB 视频，请稍候...`,
                icon: 'none',
                duration: 2000
              })
            }
            this.selectedVideoFile = res
            this.startUpload(res)
          }
        },
        fail: (err) => {
          if (err.errMsg && err.errMsg.includes('cancel')) this.uploadError = ''
          else this.uploadError = '选择视频失败'
          this.selectedVideoFile = null
        }
      })
    },
    async startUpload(videoData) {
      try {
        // 验证视频数据
        if (!videoData) {
          throw new Error('视频数据无效')
        }
        
        if (!videoData.tempFilePath) {
          throw new Error('视频文件路径无效，请重新选择视频')
        }
        
        this.uploading = true
        this.uploadProgress = 0
        this.uploadError = ''
        this.lastProgress = -1
        this.uploadTask = null
        
        const fileSizeBytes = videoData.size || 0
        const fileSizeMB = fileSizeBytes / (1024 * 1024)
        const fileSizeMBStr = fileSizeMB > 0 ? fileSizeMB.toFixed(2) : '未知'
        
        console.log('========== 开始上传视频 ==========')
        console.log('文件大小（字节）:', fileSizeBytes.toLocaleString(), 'bytes')
        console.log('文件大小（MB）:', fileSizeMBStr, 'MB')
        console.log('文件路径:', videoData.tempFilePath)
        console.log('视频时长:', videoData.duration || '未知', '秒')
        
        // 检查是否超过服务器限制
        const SERVER_MAX_SIZE_MB = 50
        if (fileSizeMB > SERVER_MAX_SIZE_MB) {
          throw new Error(`文件大小为 ${fileSizeMBStr}MB，超过服务器限制（${SERVER_MAX_SIZE_MB}MB），请压缩后重试`)
        }
        
        // 根据文件大小动态设置超时时间（每MB 20秒，最少180秒，最多600秒=10分钟）
        // 增加超时时间，给网络较慢的情况更多时间
        const estimatedTimeout = fileSizeMB > 0 
          ? Math.min(Math.max(Math.ceil(fileSizeMB * 20000), 180000), 600000)
          : 180000 // 默认180秒
        console.log('上传超时设置:', estimatedTimeout / 1000, '秒（', (estimatedTimeout / 60000).toFixed(1), '分钟）')
        console.log('================================')
        
        const uploadResult = await upload({
          url: '/common/uploadMinio',
          filePath: videoData.tempFilePath,
          name: 'file',
          timeout: estimatedTimeout,
          header: { 'Authorization': 'Bearer ' + getToken() },
          onProgress: (progress) => {
            // 防止重复触发和重复打印
            const currentProgress = Math.floor(progress || 0)
            if (currentProgress !== this.lastProgress) {
              this.uploadProgress = currentProgress
              this.lastProgress = currentProgress
              
              // 每10%或关键节点打印一次
              if (currentProgress % 10 === 0 || currentProgress === 100 || 
                  currentProgress === 25 || currentProgress === 50 || currentProgress === 75) {
                console.log('上传进度:', currentProgress + '%', '文件大小:', fileSizeMBStr, 'MB')
              }
            }
          },
          onTask: (task) => { 
            this.uploadTask = task
            console.log('上传任务已创建:', task)
          }
        })
        if (typeof uploadResult === 'string') this.uploadedVideoUrl = uploadResult
        else if (uploadResult && uploadResult.url) this.uploadedVideoUrl = uploadResult.url
        else { this.uploadError = '上传成功但无法获取视频地址'; return }
        this.$emit('upload-success', { url: this.uploadedVideoUrl, fullData: uploadResult, urlOnly: this.urlOnly })
        this.uploading = false
      } catch (error) {
        console.error('视频上传异常:', error)
        
        // 停止上传任务（如果有）
        if (this.uploadTask && this.uploadTask.abort) {
          try {
            this.uploadTask.abort()
          } catch (e) {
            console.error('停止上传任务失败:', e)
          }
        }
        
        // 处理不同类型的错误信息
        let errorMsg = '上传失败'
        const originalErrorMsg = error?.errMsg || error?.message || error?.msg || ''
        
        if (error && typeof error === 'string') {
          errorMsg = error
        } else if (error?.message) {
          errorMsg = error.message
        } else if (error?.errMsg) {
          errorMsg = error.errMsg
        } else if (error?.msg) {
          errorMsg = error.msg
        }
        
        // 检查是否是文件大小相关错误
        const fileSizeMB = videoData.size ? (videoData.size / (1024 * 1024)) : 0
        const fileSizeMBStr = fileSizeMB > 0 ? fileSizeMB.toFixed(2) : '未知'
        
        // 针对不同错误类型给出更具体的提示
        if (originalErrorMsg.includes('fail undefined') || originalErrorMsg.includes('uploadFile:fail')) {
          // 这是uni-app的常见错误，可能是网络问题、服务器问题或文件问题
          if (fileSizeMB > 30) {
            errorMsg = `上传失败（${fileSizeMBStr}MB）。可能是网络不稳定或服务器响应超时，建议压缩后重试`
          } else {
            errorMsg = `上传失败（${fileSizeMBStr}MB）。请检查网络连接后重试，或尝试压缩视频后上传`
          }
        } else if (fileSizeMB > 50 && (errorMsg.includes('fail') || errorMsg.includes('undefined'))) {
          errorMsg = `文件过大（${fileSizeMBStr}MB）或上传超时，请尝试压缩后上传或选择较小的文件`
        } else if (errorMsg.includes('timeout') || errorMsg.includes('超时')) {
          errorMsg = `上传超时（${fileSizeMBStr}MB），请检查网络连接后重试`
        } else if (fileSizeMB > 0 && fileSizeMB <= 30) {
          // 小文件上传失败，更可能是网络或服务器问题
          errorMsg = `上传失败（${fileSizeMBStr}MB）。请检查网络连接，或稍后重试`
        }
        
        this.uploadError = errorMsg
        this.uploading = false
        this.lastProgress = -1
        this.uploadTask = null
        
        // 保留文件数据，允许重试
        // this.selectedVideoFile = null  // 注释掉，允许重试
        
        this.$emit('upload-error', {
          message: errorMsg,
          errMsg: errorMsg,
          code: error && error.code,
          originalError: error,
          fileSize: videoData.size,
          canRetry: true
        })
      }
    },
    cancelUpload() { 
      // 取消上传任务
      if (this.uploadTask && this.uploadTask.abort) {
        try {
          this.uploadTask.abort()
          console.log('上传任务已取消')
        } catch (e) {
          console.error('取消上传任务失败:', e)
        }
      }
      this.uploading = false
      this.uploadProgress = 0
      this.lastProgress = -1
      this.uploadTask = null
      // 不删除文件，允许重试
      // this.selectedVideoFile = null
      this.$emit('upload-cancel')
    },
    retryUpload() { this.uploadError = ''; if (this.selectedVideoFile) this.startUpload(this.selectedVideoFile); else this.selectVideo() },
    removeVideo() {
      uni.showModal({
        title: '确认删除',
        content: '确定要删除已上传的视频吗？',
        success: (res) => {
          if (res.confirm) {
            this.uploadedVideoUrl = ''
            this.selectedVideoFile = null
            this.uploadError = ''
            this.$emit('video-removed')
          }
        }
      })
    },
    showFullscreenVideo() {
      if (!this.uploadedVideoUrl) { uni.showToast({ title: '视频地址无效', icon: 'none' }); return }
      const url = encodeURIComponent(this.uploadedVideoUrl)
      uni.navigateTo({ url: `/pages/common/videopreview/index?url=${url}` })
    },
    onThumbLoaded() {},
    onThumbError() { this.thumbError = true },
    compressVideo(videoData) {
      const originalSizeMB = (videoData.size / (1024 * 1024)).toFixed(2)
      console.log('========== 开始压缩视频 ==========')
      console.log('原始文件大小:', originalSizeMB, 'MB')
      
      uni.showLoading({ title: '压缩中，请稍候...' })
      uni.compressVideo({
        src: videoData.tempFilePath,
        quality: 'medium',
        bitrate: 1000, // 设置比特率，帮助控制文件大小
        success: (res) => {
          uni.hideLoading()
          const compressedSizeMB = res.size ? (res.size / (1024 * 1024)).toFixed(2) : '未知'
          const compressionRatio = res.size && videoData.size 
            ? ((1 - res.size / videoData.size) * 100).toFixed(1) 
            : '未知'
          
          console.log('压缩后文件大小:', compressedSizeMB, 'MB')
          console.log('压缩比例:', compressionRatio, '%')
          console.log('压缩后文件路径:', res.tempFilePath)
          console.log('============================')
          
          // 检查压缩后是否仍然超过限制
          const compressedSizeMBNum = parseFloat(compressedSizeMB)
          if (compressedSizeMBNum > 50) {
            uni.showModal({
              title: '压缩后仍过大',
              content: `压缩后文件大小为 ${compressedSizeMB}MB，仍超过服务器限制（50MB）。请选择更小的视频文件。`,
              showCancel: false
            })
            this.uploadError = `压缩后仍过大（${compressedSizeMB}MB）`
            return
          }
          
          const compressedData = { ...videoData, tempFilePath: res.tempFilePath, size: res.size }
          this.selectedVideoFile = compressedData
          uni.showToast({
            title: `压缩完成，大小: ${compressedSizeMB}MB`,
            icon: 'success',
            duration: 2000
          })
          this.startUpload(compressedData)
        },
        fail: (err) => {
          uni.hideLoading()
          console.error('压缩失败:', err)
          uni.showModal({
            title: '压缩失败',
            content: '视频压缩失败，是否尝试使用原视频上传？',
            success: (modalRes) => {
              if (modalRes.confirm) {
                const originalSizeMB = (videoData.size / (1024 * 1024)).toFixed(2)
                if (parseFloat(originalSizeMB) > 50) {
                  uni.showToast({ 
                    title: '原视频超过限制，无法上传', 
                    icon: 'none',
                    duration: 3000
                  })
                } else {
                  this.selectedVideoFile = videoData
                  this.startUpload(videoData)
                }
              }
            }
          })
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.video-upload-container { width: 100%; }
.upload-area { background: #fff; border: 2rpx solid #e0e0e0; border-radius: 12rpx; padding: 20rpx; }
.upload-btn { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 200rpx; border: 2rpx dashed #007AFF; border-radius: 12rpx; background: rgba(0, 122, 255, 0.05); }
.upload-text { margin-top: 16rpx; font-size: 26rpx; color: #007AFF; font-weight: bold; }
.upload-hint { margin-top: 8rpx; font-size: 22rpx; color: #999; }
.upload-progress { text-align: center; }
.progress-bar { width: 100%; height: 8rpx; background: #f0f0f0; border-radius: 4rpx; overflow: hidden; margin-bottom: 16rpx; }
.progress-fill { height: 100%; background: linear-gradient(90deg, #007AFF, #5AC8FA); border-radius: 4rpx; transition: width 0.3s ease; }
.progress-text { font-size: 24rpx; color: #007AFF; margin-bottom: 16rpx; display: block; }
.upload-error { text-align: center; padding: 20rpx; background: rgba(255, 71, 87, 0.1); border-radius: 12rpx; border: 2rpx solid rgba(255, 71, 87, 0.3); }
.error-text { font-size: 24rpx; color: #ff4757; margin-bottom: 16rpx; display: block; }
.uploaded-area { background: #fff; border-radius: 12rpx; overflow: hidden; }
.video-preview-wrapper { background: #fff; border-radius: 8rpx; overflow: hidden; }
.video-thumbnail-wrapper { position: relative; width: 100%; height: 240rpx; border-radius: 12rpx; overflow: hidden; background: #000; border: 2rpx solid #e0e0e0; }
.video-thumbnail { width: 100%; height: 100%; object-fit: contain; background: #000; }
.thumbnail-placeholder { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(135deg, #f0f0f0 0%, #e0e0e0 100%); display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 2; border-radius: 12rpx; }
.video-icon { font-size: 60rpx; margin-bottom: 16rpx; }
.placeholder-text { color: #666; font-size: 26rpx; font-weight: 500; }
.thumbnail-placeholder { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(135deg, #f0f0f0 0%, #e0e0e0 100%); display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 2; border-radius: 12rpx; }
.video-icon { font-size: 60rpx; margin-bottom: 16rpx; }
.placeholder-text { color: #666; font-size: 26rpx; font-weight: 500; }
.play-overlay { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100rpx; height: 100rpx; background: rgba(0, 0, 0, 0.8); border-radius: 50%; display: flex; align-items: center; justify-content: center; z-index: 999; }
.play-text { color: #fff; font-size: 40rpx; font-weight: bold; margin-left: 6rpx; }
.video-duration { position: absolute; bottom: 8rpx; right: 8rpx; background: rgba(0, 0, 0, 0.7); color: #fff; padding: 4rpx 8rpx; border-radius: 4rpx; font-size: 20rpx; }
.delete-btn { position: absolute; top: 10rpx; right: 10rpx; width: 60rpx; height: 60rpx; background: rgba(255, 71, 87, 0.9); border-radius: 50%; display: flex; align-items: center; justify-content: center; z-index: 999; }
.delete-text { color: #fff; font-size: 40rpx; font-weight: bold; line-height: 1; }
.btn-small { padding: 12rpx 24rpx; font-size: 24rpx; border-radius: 8rpx; border: 2rpx solid #007AFF; color: #007AFF; background: #fff; }
.btn-small.cancel { border-color: #999; color: #999; }
.btn-small.retry { border-color: #007AFF; color: #007AFF; background: rgba(0, 122, 255, 0.1); }

</style>


